#!/usr/bin/env python3
# coding: utf-8
# Copyright 2024 Huawei Technologies Co., Ltd
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
# ===========================================================================
import os
import platform
import glob

from ansible.module_utils.basic import AnsibleModule


class DifyUninstaller:

    def __init__(self):
        self.module = AnsibleModule(
            argument_spec=dict(
                tags=dict(type="list", required=True),
                dify_code_path=dict(type="str", required=True),
            )
        )
        self.run_tags = self.module.params["tags"]
        self.dify_code_path = os.path.expanduser(self.module.params["dify_code_path"])
        self.messages = []  # 统一日志存储列表

    def _module_failed(self):
        """失败时返回日志信息"""
        return self.module.fail_json(msg="\n".join(self.messages), rc=1, changed=False)

    def _module_success(self):
        """成功时返回日志信息"""
        return self.module.exit_json(msg="Uninstall Dify success.", rc=0, changed=True)

    def _check_docker_env(self):
        """检查Docker和Docker Compose环境"""
        self.messages.append("[ASCEND] Checking Docker and Docker Compose environment...")
        
        # 检查Docker是否安装
        docker_path = self.module.get_bin_path("docker", required=False)
        if not docker_path:
            self.messages.append("[ASCEND][ERROR] Docker not installed, please install docker first.")
            self._module_failed()
        self.messages.append("[ASCEND] Docker is installed at: {}".format(docker_path))
        
        # 检查Docker Compose版本
        compose_v2 = False
        compose_path = self.module.get_bin_path("docker-compose", required=False)
        if not compose_path:
            self.messages.append("[ASCEND] Checking docker compose v2...")
            rc, out, _ = self.module.run_command([docker_path, "compose", "version"])
            if rc != 0:
                self.messages.append("[ASCEND][ERROR] Docker Compose not installed, please install docker-compose or docker compose plugin.")
                self._module_failed()
            compose_v2 = True
            self.messages.append("[ASCEND] Docker Compose v2 is available.")
        else:
            self.messages.append("[ASCEND] Docker Compose (v1) is installed at: {}".format(compose_path))
        
        return compose_v2, docker_path, compose_path

    def _find_dify_docker_dir(self):
        """查找Dify的docker目录"""
        self.messages.append("[ASCEND] Searching for Dify source directory in: {}".format(self.dify_code_path))
        
        dify_dirs = glob.glob(os.path.join(self.dify_code_path, "dify-*/"))
        if not dify_dirs:
            self.messages.append("[ASCEND][ERROR] Dify source directory not found in {}".format(self.dify_code_path))
            self._module_failed()
        
        dify_dir = dify_dirs[0].rstrip("/")
        self.messages.append("[ASCEND] Found Dify source directory: {}".format(dify_dir))
        
        docker_dir = os.path.join(dify_dir, "docker")
        if not os.path.isdir(docker_dir):
            self.messages.append("[ASCEND][ERROR] docker directory not found in {}".format(dify_dir))
            self._module_failed()
        
        self.messages.append("[ASCEND] Found Dify docker directory: {}".format(docker_dir))
        return docker_dir

    def _stop_dify_containers(self, compose_v2, docker_path, compose_path, docker_dir):
        """停止并移除Dify容器"""
        self.messages.append("[ASCEND] Stopping Dify containers...")
        
        # 构建停止命令
        if compose_v2:
            cmd = [docker_path, "compose", "down"]
            self.messages.append("[ASCEND] Using command: {}".format(" ".join(cmd)))
        else:
            cmd = [compose_path, "down"]  
            self.messages.append("[ASCEND] Using command: {}".format(" ".join(cmd)))
        
        # 执行命令
        rc, out, err = self.module.run_command(cmd, cwd=docker_dir)
        if rc != 0:
            self.messages.append("[ASCEND][ERROR] Failed to stop Dify containers: {}".format(err))
            self._module_failed()
        
        self.messages.append("[ASCEND] Dify containers stopped successfully.")
        # 记录命令输出日志
        if out:
            self.messages.append("[ASCEND] Command output:\n{}".format(out.strip()))

    def _uninstall_dify(self):
        """主卸载流程"""
        # 检查dify_code_path参数
        if not self.module.params["dify_code_path"]:
            self.messages.append("[ASCEND][ERROR] Please provide a value for the dify_code_path parameter.")
            self._module_failed()
        self.messages.append("[ASCEND] Starting Dify uninstallation...")
        self.messages.append("[ASCEND] Dify code path: {}".format(self.dify_code_path))

        # 检查Docker环境
        compose_v2, docker_path, compose_path = self._check_docker_env()

        # 查找Docker目录
        docker_dir = self._find_dify_docker_dir()

        # 停止容器
        self._stop_dify_containers(compose_v2, docker_path, compose_path, docker_dir)

        self.messages.append("[ASCEND] Dify uninstallation completed successfully.")

    def run(self):
        """执行入口"""
        try:
            self._uninstall_dify()
        except Exception as e:
            self.messages.append("[ASCEND][ERROR] Uninstallation failed: {}".format(str(e)))
            self._module_failed()
        self._module_success()


def main():
    DifyUninstaller().run()


if __name__ == "__main__":
    main()